package com.cn.shuangzi.ad;

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.text.TextUtils;

import com.cn.shuangzi.SZManager;
import com.cn.shuangzi.ad.bean.ADPlatform;
import com.cn.shuangzi.ad.retrofit.ADHttpRequestRetrofitService;
import com.cn.shuangzi.ad.retrofit.ADRequestInterceptor;
import com.cn.shuangzi.ad.util.tt.TTAdManagerHolder;
import com.cn.shuangzi.bean.MaterialsInfo;
import com.cn.shuangzi.retrofit.SZRetrofitManager;
import com.cn.shuangzi.retrofit.SZRetrofitResponseListener;
import com.cn.shuangzi.util.SZUtil;
import com.cn.shuangzi.util.SZValidatorUtil;
import com.cn.shuangzi.util.SZXmlUtil;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.qq.e.comm.managers.GDTADManager;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.cn.shuangzi.ad.util.ADConst.AD_LOAD_NATIVE_POLICY;
import static com.cn.shuangzi.ad.util.ADConst.AD_LOAD_POLICY;
import static com.cn.shuangzi.ad.util.ADConst.AD_LOAD_SELF_BANNER_POLICY;
import static com.cn.shuangzi.ad.util.ADConst.AD_LOAD_SELF_FLOAT_POLICY;
import static com.cn.shuangzi.ad.util.ADConst.AD_LOAD_SPLASH_POLICY;
import static com.cn.shuangzi.ad.util.ADConst.AD_LOCAL_ERROR_EVENT_ID;
import static com.cn.shuangzi.ad.util.ADConst.AD_PLATFORM_LOCAL;
import static com.cn.shuangzi.ad.util.ADConst.AD_READ_LOCAL_EVENT_ID;
import static com.cn.shuangzi.ad.util.ADConst.AD_SHOWN_COMPANY;
import static com.cn.shuangzi.ad.util.ADConst.ERROR_CODE;
import static com.cn.shuangzi.ad.util.ADConst.ERROR_MSG;
import static com.cn.shuangzi.ad.util.ADConst.TAG_SPLASH;
import static com.cn.shuangzi.retrofit.SZRetrofitManager.ERROR_NET_FAILED;

/**
 * Created by CN.
 */

public class ADManager {
    private static ADManager INSTANCE;
    private SZXmlUtil sZXmlUtil;

    private int mLifecycleCount = 0;
    private long activityHideTime = 0;
    private static long INTERVAL_SPLASH_AD_SHOW = 1 * 60 * 1000;
    private OnSplashAdShowListener onSplashAdShowListener;
    private ADHttpRequestRetrofitService adHttpRequestRetrofitService;

    private ADManager() {
        if (sZXmlUtil == null) {
            sZXmlUtil = new SZXmlUtil(SZManager.getInstance().getContext(), AD_LOAD_POLICY);
        }
        GDTADManager.getInstance().initWith(SZManager.getInstance().getContext(), SZUtil.getGDT_APPID(SZManager.getInstance().getContext()));
        TTAdManagerHolder.init(SZManager.getInstance().getContext(), SZManager.getInstance().isDebugMode());
    }

    public static ADManager getInstance() {
        if (INSTANCE == null) {
            synchronized (ADManager.class) {
                if (INSTANCE == null) {
                    INSTANCE = new ADManager();
                }
            }
        }
        return INSTANCE;
    }

    public void setAdShownCompany(String company) {
        sZXmlUtil.put(AD_SHOWN_COMPANY, company);
    }

    public void removeAdShownCompany() {
        sZXmlUtil.remove(AD_SHOWN_COMPANY);
    }

    public String getAdShownCompany() {
        return sZXmlUtil.getString(AD_SHOWN_COMPANY);
    }

    public boolean isShowAd() {
        if (sZXmlUtil == null) {
            sZXmlUtil = new SZXmlUtil(SZManager.getInstance().getContext(), AD_LOAD_POLICY);
        }
        String data = sZXmlUtil.getString(AD_LOAD_SPLASH_POLICY);
        if (data != null && !data.equals("")) {
            try {
                List<ADPlatform> adPlatformList = new Gson().fromJson(data, new TypeToken<List<ADPlatform>>() {
                }.getType());
                if (adPlatformList != null && adPlatformList.size() > 0) {
                    return adPlatformList.get(0).isAdIsOpen();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    public ADHttpRequestRetrofitService getADApiService() {
        if (adHttpRequestRetrofitService == null) {
            adHttpRequestRetrofitService = SZRetrofitManager.getInstance().getRetrofit("https://switch.api.shuangzikeji.cn:8080/", new ADRequestInterceptor()).create(ADHttpRequestRetrofitService.class);
        }
        return adHttpRequestRetrofitService;
    }

    public void getSelfAd(String channel, String packageName, String version, final OnSplashADLoadListener onSplashADLoadListener) {
        SZRetrofitManager.getInstance().request(getADApiService().getAd(channel, packageName, version, "ALL"), TAG_SPLASH, new SZRetrofitResponseListener.SimpleSZRetrofitResponseListener() {
            @Override
            public void onSuccess(String data) {
                List<ADPlatform> adPlatformList = new Gson().fromJson(data, new TypeToken<List<ADPlatform>>() {
                }.getType());
                List<ADPlatform> adSelfBannerList = new ArrayList<>();
                List<ADPlatform> adSelfFloatList = new ArrayList<>();
                if(SZValidatorUtil.isValidList(adPlatformList)) {
                    for (ADPlatform adPlatform : adPlatformList) {
                        switch (adPlatform.getAdType()) {
                            case ADPlatform.AD_TYPE_BANNER:
                                if (adPlatform.isSelfAd()) {
                                    adSelfBannerList.add(adPlatform);
                                }
                                break;
                            case ADPlatform.AD_TYPE_GIFT_BOX:
                                if (adPlatform.isSelfAd()) {
                                    adSelfFloatList.add(adPlatform);
                                }
                                break;
                        }
                    }
                }
                if(SZValidatorUtil.isValidList(adSelfBannerList)) {
                    sZXmlUtil.put(AD_LOAD_SELF_BANNER_POLICY, new Gson().toJson(adSelfBannerList));
                }else{
                    sZXmlUtil.remove(AD_LOAD_SELF_BANNER_POLICY);
                }
                if(SZValidatorUtil.isValidList(adSelfFloatList)) {
                    sZXmlUtil.put(AD_LOAD_SELF_FLOAT_POLICY, new Gson().toJson(adSelfFloatList));
                }else{
                    sZXmlUtil.remove(AD_LOAD_SELF_FLOAT_POLICY);
                }
                if (onSplashADLoadListener != null) {
                    onSplashADLoadListener.onFetchAdSuccess(null);
                }
            }

            @Override
            public void onNetError(int errorCode, String errorMsg) {
                SZManager.getInstance().onUMEvent(AD_LOCAL_ERROR_EVENT_ID, getErrorEventMap(AD_PLATFORM_LOCAL, String.valueOf(errorCode), errorMsg));
                SZUtil.log("errorCode:" + errorCode + "|errorMsg:" + errorMsg);
                if (errorCode == 4022044) {
                    sZXmlUtil.remove(AD_LOAD_SPLASH_POLICY);
                    sZXmlUtil.remove(AD_LOAD_NATIVE_POLICY);
                }
                if (onSplashADLoadListener != null) {
                    if (errorCode == 502 || errorCode == ERROR_NET_FAILED) {
                        SZManager.getInstance().onUMEvent(AD_READ_LOCAL_EVENT_ID);
                    }
                    onSplashADLoadListener.onFetchAdError();
                }
            }
        });
    }

    public void getSplash(String channel, String packageName, String version, final OnSplashADLoadListener onSplashADLoadListener) {
        SZRetrofitManager.getInstance().request(getADApiService().getAd(channel, packageName, version, "ALL"), TAG_SPLASH, new SZRetrofitResponseListener.SimpleSZRetrofitResponseListener() {
            @Override
            public void onSuccess(String data) {
                List<ADPlatform> adPlatformList = new Gson().fromJson(data, new TypeToken<List<ADPlatform>>() {
                }.getType());

                List<ADPlatform> adSplashList = new ArrayList<>();
                List<ADPlatform> adNativeList = new ArrayList<>();
                List<ADPlatform> adSelfBannerList = new ArrayList<>();
                List<ADPlatform> adSelfFloatList = new ArrayList<>();
                if(SZValidatorUtil.isValidList(adPlatformList)) {
                    for (ADPlatform adPlatform : adPlatformList) {
                        switch (adPlatform.getAdType()) {
                            case ADPlatform.AD_TYPE_SPLASH:
                                adSplashList.add(adPlatform);
                                break;
                            case ADPlatform.AD_TYPE_NATIVE:
                                adNativeList.add(adPlatform);
                                break;
                            case ADPlatform.AD_TYPE_BANNER:
                                if (adPlatform.isSelfAd()) {
                                    adSelfBannerList.add(adPlatform);
                                }
                                break;
                            case ADPlatform.AD_TYPE_GIFT_BOX:
                                if (adPlatform.isSelfAd()) {
                                    adSelfFloatList.add(adPlatform);
                                }
                                break;
                        }
                    }
                }
                String adShowCompany = getAdShownCompany();

                try {
                    if (isSwitchModeAd(adNativeList)) {
                        List<ADPlatform> adNativeSwitchList = getShowPlatform(adNativeList, adShowCompany);
                        sZXmlUtil.put(AD_LOAD_NATIVE_POLICY, new Gson().toJson(adNativeSwitchList));
                    } else {
                        sZXmlUtil.put(AD_LOAD_NATIVE_POLICY, new Gson().toJson(adNativeList));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if(SZValidatorUtil.isValidList(adSelfBannerList)) {
                    sZXmlUtil.put(AD_LOAD_SELF_BANNER_POLICY, new Gson().toJson(adSelfBannerList));
                }else{
                    sZXmlUtil.remove(AD_LOAD_SELF_BANNER_POLICY);
                }
                if(SZValidatorUtil.isValidList(adSelfFloatList)) {
                    sZXmlUtil.put(AD_LOAD_SELF_FLOAT_POLICY, new Gson().toJson(adSelfFloatList));
                }else{
                    sZXmlUtil.remove(AD_LOAD_SELF_FLOAT_POLICY);
                }

                if (isSwitchModeAd(adSplashList)) {
                    List<ADPlatform> adSplashSwitchList = getShowPlatform(adSplashList, adShowCompany);
                    sZXmlUtil.put(AD_LOAD_SPLASH_POLICY, new Gson().toJson(adSplashSwitchList));
                    if (onSplashADLoadListener != null) {
                        onSplashADLoadListener.onFetchAdSuccess(adSplashSwitchList);
                    }
                } else {
                    removeAdShownCompany();
                    sZXmlUtil.put(AD_LOAD_SPLASH_POLICY, new Gson().toJson(adSplashList));
                    if (onSplashADLoadListener != null) {
                        onSplashADLoadListener.onFetchAdSuccess(adSplashList);
                    }
                }
            }

            @Override
            public void onNetError(int errorCode, String errorMsg) {
                SZManager.getInstance().onUMEvent(AD_LOCAL_ERROR_EVENT_ID, getErrorEventMap(AD_PLATFORM_LOCAL, String.valueOf(errorCode), errorMsg));
                SZUtil.log("errorCode:" + errorCode + "|errorMsg:" + errorMsg);
                if (errorCode == 4022044) {
                    sZXmlUtil.remove(AD_LOAD_SPLASH_POLICY);
                    sZXmlUtil.remove(AD_LOAD_NATIVE_POLICY);
                }
                if (onSplashADLoadListener != null) {
                    if (errorCode == 502 || errorCode == ERROR_NET_FAILED) {
                        SZManager.getInstance().onUMEvent(AD_READ_LOCAL_EVENT_ID);
                        String data = sZXmlUtil.getString(AD_LOAD_SPLASH_POLICY);
                        if (data != null && !data.equals("")) {
                            try {
                                List<ADPlatform> adPlatformList = new Gson().fromJson(data, new TypeToken<List<ADPlatform>>() {
                                }.getType());
                                if (isSwitchModeAd(adPlatformList)) {
                                    List<ADPlatform> adSplashSwitchList = getShowPlatform(adPlatformList, getAdShownCompany());
                                    onSplashADLoadListener.onFetchAdSuccess(adSplashSwitchList);
                                } else {
                                    onSplashADLoadListener.onFetchAdSuccess(adPlatformList);
                                }
                                return;
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    onSplashADLoadListener.onFetchAdError();
                }
            }
        });
    }

    private boolean isSwitchModeAd(List<ADPlatform> adPlatformList) {
        if (SZValidatorUtil.isValidList(adPlatformList)) {
            for (ADPlatform adPlatform : adPlatformList) {
                if (isSwitchModeAd(adPlatform)) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean isSwitchModeAd(ADPlatform adPlatform) {
        if (adPlatform == null || adPlatform.getAdShowTypeInfo() == null || adPlatform.getAdShowTypeInfo().getShowType() == null) {
            return false;
        }
        return "1".equals(adPlatform.getAdShowTypeInfo().getShowType());
    }

    private List<ADPlatform> getShowPlatform(List<ADPlatform> adPlatformList, String adShowCompany) {
        if (!TextUtils.isEmpty(adShowCompany)) {
            List<ADPlatform> adPlatformSortList = new ArrayList<>();
            if (SZValidatorUtil.isValidList(adPlatformList)) {
                for (ADPlatform adPlatform : adPlatformList) {
                    if (!adShowCompany.equalsIgnoreCase(adPlatform.getAdSupportType())) {
                        adPlatformSortList.add(adPlatform);
                        adPlatformList.remove(adPlatform);
                        break;
                    }
                }
                if (SZValidatorUtil.isValidList(adPlatformList)) {
                    adPlatformSortList.add(adPlatformList.get(0));
                }
            }
            return adPlatformSortList;
        }
        return adPlatformList;
    }

    public List<MaterialsInfo> getSelfBannerList() {
        List<MaterialsInfo> materialsInfoList = new ArrayList<>();
        try {
            String banner = sZXmlUtil.getString(AD_LOAD_SELF_BANNER_POLICY);
            if (SZValidatorUtil.isValidString(banner)) {
                List<ADPlatform> bannerList = new Gson().fromJson(banner, new TypeToken<List<ADPlatform>>() {
                }.getType());
                if (bannerList != null) {
                    for (ADPlatform adPlatform : bannerList) {
                        materialsInfoList.add(adPlatform.getMaterialsInfo());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return materialsInfoList;
    }

    public MaterialsInfo getSelfFloat() {
        try {
            String giftBox = sZXmlUtil.getString(AD_LOAD_SELF_FLOAT_POLICY);
            if (SZValidatorUtil.isValidString(giftBox)) {
                List<ADPlatform> floatList = new Gson().fromJson(giftBox, new TypeToken<List<ADPlatform>>() {
                }.getType());
                if (floatList != null) {
                    for (ADPlatform adPlatform : floatList) {
                        return adPlatform.getMaterialsInfo();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public Map<String, String> getErrorEventMap(String platform, String errorCode, String errorMsg) {
        Map<String, String> params = new HashMap<>();
        try {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(ERROR_MSG, errorMsg);
            jsonObject.put(ERROR_CODE, errorCode);
            params.put(platform, jsonObject.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return params;
    }

    public interface OnSplashADLoadListener {
        void onFetchAdSuccess(List<ADPlatform> adPlatformList);

        void onFetchAdError();
    }


    public void registerActivityLifecycle(Application application, OnSplashAdShowListener onSplashAdShowListener) {
        this.onSplashAdShowListener = onSplashAdShowListener;
        application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            }

            @Override
            public void onActivityStarted(Activity activity) {
                mLifecycleCount++;
                //mLifecycleCount ==1，说明是从后台到前台
                if (mLifecycleCount == 1) {
                    if (activityHideTime > 0 && (System.currentTimeMillis() - activityHideTime) > INTERVAL_SPLASH_AD_SHOW) {
                        if (ADManager.this.onSplashAdShowListener != null) {
                            ADManager.this.onSplashAdShowListener.onSplashAdShow();
                        }
                    }
                }
            }

            @Override
            public void onActivityResumed(Activity activity) {
            }

            @Override
            public void onActivityPaused(Activity activity) {
            }

            @Override
            public void onActivityStopped(Activity activity) {
                mLifecycleCount--;
                //如果mFinalCount ==0，说明是前台到后台
                if (mLifecycleCount == 0) {
                    activityHideTime = System.currentTimeMillis();
                }
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            }

            @Override
            public void onActivityDestroyed(Activity activity) {
            }
        });
    }

    public static void setIntervalSplashAd(long interval) {
        ADManager.INTERVAL_SPLASH_AD_SHOW = interval;
    }

    public boolean isAppForeground() {
        if (this.onSplashAdShowListener == null) {
            throw new IllegalArgumentException("do not set onActivityLifecycleChangeListener yet!");
        }
        return mLifecycleCount == 1;
    }

    public interface OnSplashAdShowListener {
        void onSplashAdShow();
    }
}
